#include <iostream>
#include <vector>
#include <string>

#include <cstdio>

#include <sds/sfile.h>
#include <sds/sdataset.h>
#include <sds/sdataview.h>

using namespace std;
using namespace sds;

void Read(const string& srcname, const string& chkname,
	  SDataView<unsigned char>& src, SDataView<unsigned char>& chk,
	  vector<SInteger>& size) {
  SFile srcfile(srcname);
  src = srcfile.getDataset(0).getDataView<unsigned char>();
  SFile chkfile(chkname);
  chk = chkfile.getDataset(0).getDataView<unsigned char>();
  size = src.getSize();
}

int main(int argc, const char *argv[]) {
  SDataView<unsigned char> src;
  SDataView<unsigned char> chk;

  vector<SInteger> size;

  Read(argv[1], argv[2], src, chk, size);

  int all = 0, good = 0;
  int cr[256][256], c[256], s[256];
  
  for (int i = 0; i < 256; ++i) {
    for (int j = 0; j < 256; ++j) {
      cr[i][j] = 0;
    }
    c[i] = 0; s[i] = 0;
  }
  
  for (int i = 0; i < size[0]; ++i) {
    for (int j = 0; j < size[1]; ++j) {
      if (chk[i][j] != 0) {
	++all;
	if (chk[i][j] == src[i][j]) {
	  ++good;
	}
	++cr[chk[i][j]][src[i][j]];
	++c[chk[i][j]];
	++s[src[i][j]];
      }
    }
  }
  cout << "Quality: " << (double)good / all << endl;
  cout << '\t';
  for (int j = 0; j < 256; ++j) {
      if (s[j] == 0 && c[j] == 0) continue;
      cout << '#' << j << '\t';    
  }
  cout << endl;
  for (int i = 1; i < 256; ++i) {
    if (c[i] == 0) continue;
    cout << '#' << i << '\t';
    for (int j = 0; j < 256; ++j) {
      if (s[j] == 0 && c[j] == 0) continue;
      cout << cr[i][j] << '\t';
    }
    cout << endl;
  }
  return 0;
}
